// 压力测试 Worker
let isRunning = false;
let requestCount = 0;
let successCount = 0;
let failureCount = 0;
let startTime = 0;
let activeRequests = new Set(); // 跟踪活动请求

function sendRequest(url, ip, mode) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    const startTime = Date.now();
    
    // 将请求添加到活动集合
    activeRequests.add(xhr);
    
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
        // 从活动集合中移除
        activeRequests.delete(xhr);
        
        const endTime = Date.now();
        const responseTime = endTime - startTime;
        
        if (xhr.status >= 200 && xhr.status < 400) {
          resolve({
            success: true,
            statusCode: xhr.status,
            responseTime,
            data: xhr.responseText
          });
        } else {
          resolve({
            success: false,
            statusCode: xhr.status,
            responseTime,
            error: 'HTTP Error'
          });
        }
      }
    };
    
    xhr.onerror = function() {
      // 从活动集合中移除
      activeRequests.delete(xhr);
      
      const endTime = Date.now();
      resolve({
        success: false,
        responseTime: endTime - startTime,
        error: 'Network Error'
      });
    };
    
    xhr.ontimeout = function() {
      // 从活动集合中移除
      activeRequests.delete(xhr);
      
      const endTime = Date.now();
      resolve({
        success: false,
        responseTime: endTime - startTime,
        error: 'Timeout'
      });
    };

    try {
      xhr.open('GET', mode === 'dos' ? `http://${ip}:80` : url, true);
      xhr.timeout = mode === 'dos' ? 2000 : 5000;
      xhr.setRequestHeader('Cache-Control', 'no-cache');
      xhr.setRequestHeader('Pragma', 'no-cache');
      xhr.send();
    } catch (error) {
      // 从活动集合中移除
      activeRequests.delete(xhr);
      
      const endTime = Date.now();
      resolve({
        success: false,
        responseTime: endTime - startTime,
        error: error.message
      });
    }
  });
}

async function runBatch(config) {
  const batchSize = 100;
  const requests = [];
  
  for (let i = 0; i < batchSize; i++) {
    if (!isRunning) break;
    
    requests.push(
      sendRequest(config.url, config.ip, config.mode)
        .then(result => {
          if (isRunning) { // 只在仍在运行时更新计数
            requestCount++;
            if (result.success) {
              successCount++;
            } else {
              failureCount++;
            }
          }
          return result;
        })
    );
  }
  
  try {
    const results = await Promise.all(requests);
    if (!isRunning) return; // 如果已停止，不发送统计数据
    
    const now = Date.now();
    const elapsed = (now - startTime) / 1000;
    
    // 发送统计数据到主线程
    self.postMessage({
      type: 'stats',
      data: {
        totalRequests: requestCount,
        successRequests: successCount,
        failedRequests: failureCount,
        requestsPerSecond: Math.floor(requestCount / elapsed),
        results
      }
    });
    
    // 继续下一批
    if (isRunning) {
      setTimeout(() => runBatch(config), 0);
    }
  } catch (error) {
    console.error('Batch error:', error);
    if (isRunning) {
      setTimeout(() => runBatch(config), 100);
    }
  }
}

function cleanup() {
  // 取消所有活动的请求
  activeRequests.forEach(xhr => {
    try {
      xhr.abort();
    } catch (error) {
      console.error('取消请求时出错:', error);
    }
  });
  activeRequests.clear();
  
  // 发送最终统计数据
  const now = Date.now();
  const elapsed = (now - startTime) / 1000;
  
  self.postMessage({
    type: 'stats',
    data: {
      totalRequests: requestCount,
      successRequests: successCount,
      failedRequests: failureCount,
      requestsPerSecond: Math.floor(requestCount / elapsed),
      results: []
    }
  });
}

self.onmessage = function(e) {
  const { type, config } = e.data;
  
  switch (type) {
    case 'start':
      isRunning = true;
      requestCount = 0;
      successCount = 0;
      failureCount = 0;
      startTime = Date.now();
      activeRequests.clear();
      
      // 启动多个并发批次
      const workerCount = Math.ceil(config.concurrentUsers / 100);
      for (let i = 0; i < workerCount; i++) {
        setTimeout(() => runBatch(config), i * 25);
      }
      break;
      
    case 'stop':
      isRunning = false;
      cleanup();
      break;
  }
}; 